<template>
  <!-- 添加或修改人员分组对话框 -->
  <el-dialog :title="dialog.title" v-model="dialog.visible" width="740px" append-to-body>
    <el-form ref="personGroupFormRef" :model="form" :rules="rules" label-width="80px">
      <el-form-item label="父分组id" prop="parentId">
        <el-tree-select
          disabled
          v-model="form.parentId"
          :data="personGroupOptions"
          :props="{ value: 'groupId', label: 'groupName', children: 'children' }"
          value-key="groupId"
          placeholder="请选择父分组id"
          check-strictly
          style="width: 100%;"
        />
      </el-form-item>
      <!-- <el-form-item label="祖级列表" prop="ancestors">
        <el-input v-model="form.ancestors" type="textarea" placeholder="请输入内容" />
      </el-form-item> -->
      <el-form-item label="分组名称" prop="groupName">
        <el-input v-model="form.groupName" placeholder="请输入分组名称" />
      </el-form-item>
      <el-form-item label="分组人员">
        <tree-transfer
          ref="treeTransferRef"
          :nodeKey="'id'"
          :fromData="fromData"
          :toData="toData"
          :defaultProps="transferProps"
          :leftTit="'可选菜单'"
          :rightTit="'已选菜单'"
          @checkVal="checkVal"
        />
      </el-form-item>
      <!-- <el-form-item label="是否系统分组：1是，0否" prop="isSystem">
        <el-input v-model="form.isSystem" placeholder="请输入是否系统分组：1是，0否" />
      </el-form-item> -->
      <!-- <el-form-item label="显示顺序" prop="orderNum">
        <el-input v-model="form.orderNum" placeholder="请输入显示顺序" />
      </el-form-item> -->
      <el-form-item label="备注" prop="remark">
        <el-input v-model="form.remark" placeholder="请输入备注" />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup name="PersonGroup" lang="ts">
import { listPersonGroup, getPersonGroup, delPersonGroup, addPersonGroup, updatePersonGroup } from '@/api/device/personGroup';
import { PersonGroupVO, PersonGroupQuery, PersonGroupForm } from '@/api/device/personGroup/types';
import { studentTree } from '@/api/office/student';
import api from '@/api/system/user';

type PersonGroupOption = {
  groupId: number;
  groupName: string;
  children?: PersonGroupOption[];
};

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

const personGroupList = ref<PersonGroupVO[]>([]);
const personGroupOptions = ref<PersonGroupOption[]>([]);
const buttonLoading = ref(false);
const showSearch = ref(true);
const isExpandAll = ref(true);
const loading = ref(false);

const queryFormRef = ref<ElFormInstance>();
const personGroupFormRef = ref<ElFormInstance>();
const personGroupTableRef = ref<ElTableInstance>();

const treeTransferRef = ref(); // 树形穿梭框
const fromData = ref([]); // 树形数据
const toData = ref([]); // 选中的ids数据
const transferProps = ref({ value: 'id', label: 'label', children: 'children', disabled: 'disabled', pid: 'parentId' });
const memberIds = ref<any[]>([]);
const dialog = reactive<DialogOption>({
  visible: false,
  title: ''
});
const emit = defineEmits(['onSuccess']);

const initFormData: PersonGroupForm = {
  groupId: undefined,
  parentId: undefined,
  ancestors: undefined,
  groupName: undefined,
  groupType: undefined,
  isSystem: 0,
  orderNum: 0,
  status: '0',
  remark: undefined
};

const data = reactive<PageData<PersonGroupForm, PersonGroupQuery>>({
  form: { ...initFormData },
  queryParams: {
    parentId: undefined,
    ancestors: undefined,
    groupName: undefined,
    groupType: undefined,
    isSystem: undefined,
    orderNum: undefined,
    status: undefined,
    params: {}
  },
  rules: {
    groupId: [{ required: true, message: '分组id不能为空', trigger: 'blur' }],
    parentId: [{ required: true, message: '父分组id不能为空', trigger: 'blur' }],
    // ancestors: [{ required: true, message: '祖级列表不能为空', trigger: 'blur' }],
    groupName: [{ required: true, message: '分组名称不能为空', trigger: 'blur' }],
    groupType: [{ required: true, message: '分组类型：1学生；2教职工；3校外人员不能为空', trigger: 'change' }]
    // isSystem: [{ required: true, message: '是否系统分组：1是，0否不能为空', trigger: 'blur' }],
    // orderNum: [{ required: true, message: '显示顺序不能为空', trigger: 'blur' }],
    // status: [{ required: true, message: '状态不能为空', trigger: 'change' }],
    // remark: [{ required: true, message: '备注不能为空', trigger: 'blur' }]
  }
});

const { queryParams, form, rules } = toRefs(data);

/** 查询人员分组列表 */
const getList = async () => {
  loading.value = true;
  const res = await listPersonGroup(queryParams.value);
  const data = proxy?.handleTree<PersonGroupVO>(res.data, 'groupId', 'parentId');
  if (data) {
    personGroupList.value = data;
    loading.value = false;
  }
};

/** 查询人员分组下拉树结构 */
const getTreeselect = async () => {
  const res = await listPersonGroup();
  personGroupOptions.value = [];
  const data: PersonGroupOption = { groupId: 0, groupName: '顶级节点', children: [] };
  data.children = proxy?.handleTree<PersonGroupOption>(res.data, 'groupId', 'parentId');
  personGroupOptions.value.push(data);
};

// 取消按钮
const cancel = () => {
  reset();
  dialog.visible = false;
};

// 表单重置
const reset = () => {
  form.value = { ...initFormData };
  fromData.value = [];
  toData.value = [];
  treeTransferRef.value?.clearData();
  personGroupFormRef.value?.resetFields();
};

/** 搜索按钮操作 */
const handleQuery = () => {
  getList();
};

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields();
  handleQuery();
};

/** 新增按钮操作 */
const handleAdd = async (row?: PersonGroupVO) => {
  reset();
  getTreeselect();
  if (row != null && row.groupId) {
    form.value.parentId = row.groupId;
    form.value.groupType = row.groupType;
  } else {
    form.value.parentId = 0;
  }
  await loadFromData();
  dialog.visible = true;
  dialog.title = '添加人员分组';
};

/** 展开/折叠操作 */
const handleToggleExpandAll = () => {
  isExpandAll.value = !isExpandAll.value;
  toggleExpandAll(personGroupList.value, isExpandAll.value);
};

/** 展开/折叠操作 */
const toggleExpandAll = (data: PersonGroupVO[], status: boolean) => {
  data.forEach((item) => {
    personGroupTableRef.value?.toggleRowExpansion(item, status);
    if (item.children && item.children.length > 0) toggleExpandAll(item.children, status);
  });
};

/** 修改按钮操作 */
const handleUpdate = async (row: PersonGroupVO) => {
  reset();
  await getTreeselect();
  if (row != null) {
    form.value.parentId = row.parentId;
    form.value.groupType = row.groupType;
  }
  await loadFromData();
  const res = await getPersonGroup(row.groupId);
  Object.assign(form.value, res.data);
  dialog.visible = true;
  dialog.title = '修改人员分组';
};

/** 提交按钮 */
const submitForm = () => {
  personGroupFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      buttonLoading.value = true;
      form.value.memberIds = memberIds.value;
      if (form.value.groupId) {
        await updatePersonGroup(form.value).finally(() => (buttonLoading.value = false));
      } else {
        await addPersonGroup(form.value).finally(() => (buttonLoading.value = false));
      }
      proxy?.$modal.msgSuccess('操作成功');
      dialog.visible = false;
      emit('onSuccess');
    }
  });
};

/** 删除按钮操作 */
const handleDelete = async (row: PersonGroupVO) => {
  await proxy?.$modal.confirm('是否确认删除人员分组编号为"' + row.groupId + '"的数据项？');
  loading.value = true;
  await delPersonGroup(row.groupId).finally(() => (loading.value = false));
  emit('onSuccess');
  proxy?.$modal.msgSuccess('删除成功');
};

/**
 * 将选中菜单存入表单
 * @param val 子组件穿梭框返回
 */
const checkVal = (val: any) => {
  const arr = [];
  for (const i of val) {
    if (!i.children) {
      arr.push(i.id);
    }
  }
  memberIds.value = arr;
};

const loadFromData = async () => {
  if (form.value.groupType === '1') {
    const res = await studentTree();
    fromData.value = res.data;
  } else if (form.value.groupType === '2') {
    const res = await api.deptUserTreeSelect();
    fromData.value = res.data;
  }
  setTimeout(() => {
    treeTransferRef.value?.initData();
  }, 1);
};

defineExpose({
  handleAdd,
  handleUpdate,
  handleDelete
});
</script>
